package com.pclong.fightlandlordserver;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.pclong.fightlandlordserver.command.message.F3ServerMessage;
import com.pclong.fightlandlordserver.command.message.PlayerMessage;
import com.pclong.fightlandlordserver.data.HibernateSessionFactory;
import com.pclong.fightlandlordserver.data.metadata.PlayerProfile;
import com.pclong.fightlandlordserver.game.model.EntityInfo;
import com.pclong.fightlandlordserver.game.model.Player;
import com.pclong.fightlandlordserver.game.model.Room;
import com.pclong.fightlandlordserver.model.PlayerResult;
import com.pclong.fightlandlordserver.model.RoomResult;
import com.pclong.fightlandlordserver.service.DataService;
import com.pclong.fightlandlordserver.service.F3SWebServiceResult;
import com.pclong.fightlandlordserver.util.ConvertUtil;
import com.pclong.fightlandlordserver.util.ModelUtil;
import com.pclong.fightlandlordserver.util.PropertiesHelper;
import com.pclong.fightlandlordserver.util.StringUtil;
import java.util.logging.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import java.net.*;
import java.io.*;
import java.util.*;
import java.util.List;
import java.util.Map;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import org.apache.commons.codec.binary.Base64;
import org.hibernate.criterion.Restrictions;

/**
 *
 * @author long@7road.com
 * @Date 2012-2-29,10:21:14
 * @Description ServerChat类
 */
public class App {

    private static final Logger log = LogManager.getLogger(App.class);
    private ServerSocket server;
    private BManager bMan = new BManager();//消息广播者
    private static Gson gson = new GsonBuilder().setPrettyPrinting().create();

    public App() {
    }  //构造函数

    void startServer() //启动服务器
    {
        try {
            server = new ServerSocket(2009); //创建服务器套接字
            System.out.println("服务器套接字建立完毕");
            while (true) {
                Socket socket = server.accept();//若客户机提请求，socket连接                
                new Chat_Thread(socket).start();//启动线程
                bMan.add(socket);//添加套接字
                bMan.sendClientInfo();//使用套接字输出当前聊天人数
            }
        } catch (Exception e) {
            System.out.println(e);
        }
    }

    public static void main(String[] args) {
//        App server = new App();
//        server.startServer();
//        System.out.println( ConfigService.getTankAgentConfig().LoginEnabled);  
//        System.out.println(ConfigService.getTankAgentConfig().getTheme());
//         UserConfigEntity user = DataService.Login("long","long");
//         if(user==null){
//             System.out.println("null");
//         }else{
//             System.out.println("long");
//         }

//        String a="<ConstainFight><info createDate=\"2012-03-13 07:13:40.631\"/><fightItems orderId=\"1\" ConsortiaName=\"名爵宫\" Levels=\"10\" FightPower=\"3509759\"/></ConstainFight>";
//        System.out.println(a.replaceFirst("<[^<>]*/>", ""));

//          F3ServerMessage resultMessage = new PlayerMessage();
//          resultMessage.setContent("Content");
//          resultMessage.setNumber(100);
//          resultMessage.setSignature("345");         
//          Gson gson = new GsonBuilder().setPrettyPrinting().create();
//         System.out.println(gson.toJson(resultMessage));
/*
        EntityInfo<PlayerProfile> info = new EntityInfo<PlayerProfile>();
        // 添加新用户
        PlayerProfile playerProfile = new PlayerProfile();
        playerProfile.setProfileId(UUID.randomUUID().toString());
        playerProfile.setName("USER_ID");
        playerProfile.setUserId("USER_ID");
        playerProfile.setPassword("PASSWORD");
        playerProfile.setRlsPath("RLS_PATH");
        playerProfile.setCurrentScore(0d);
        playerProfile.setInitLimit(100);
        playerProfile.setLevel(new Integer(0));
        playerProfile.setRole("ROLE");
        playerProfile.setStatus("STATUS"); // 0:禁用、1:启用
        playerProfile.setCreateBy("CURRENT_USER_ID");
        playerProfile.setUpdateBy("CURRENT_USER_ID");
        info.setEntity(playerProfile);
        info.setResult(F3SWebServiceResult.SUCCESS);
        String result = toXML(info, new Class[]{PlayerProfile.class});
        System.out.println(result);*/
//        String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE properties SYSTEM \"http://java.sun.com/dtd/properties.dtd\"><properties>    <entry key=\"plugin.TestPlugin\">com.plugin.test.TestPluginModule</entry>    <entry key=\"messages.TestPlugin\">TestPluginMessages.properties</entry></properties>";
        /*
        String xml="<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE properties SYSTEM \"http://java.sun.com/dtd/properties.dtd\"><properties> <entry key=\"PLATFORM\">id=1,parentId=-1,name=ddzplatform,displayIndex=1,modelCategory=platform,disabled=false,childLimit=1</entry> <entry key=\"LOBBY\">id=1,parentId=1,name=ddzlobby,displayIndex=1,modelCategory=LOBBY,disabled=false,childLimit=12</entry>	<entry key=\"ROOM\">id=1,parentId=1,name=ROOM1,displayIndex=1,modelCategory=ROOM,disabled=false,childLimit=3,lowLevelMark=1,midLevelMark=2,highLevelMark=3;id=2,parentId=1,name=ROOM2,displayIndex=2,modelCategory=ROOM,disabled=false,childLimit=3,lowLevelMark=1,midLevelMark=2,highLevelMark=3;id=3,parentId=1,name=ROOM3,displayIndex=3,modelCategory=ROOM,disabled=false,childLimit=3,lowLevelMark=1,midLevelMark=2,highLevelMark=3;id=4,parentId=1,name=ROOM4,displayIndex=4,modelCategory=ROOM,disabled=false,childLimit=3,lowLevelMark=1,midLevelMark=2,highLevelMark=3;id=5,parentId=1,name=ROOM5,displayIndex=5,modelCategory=ROOM,disabled=false,childLimit=3,lowLevelMark=1,midLevelMark=2,highLevelMark=3;id=6,parentId=1,name=ROOM6,displayIndex=6,modelCategory=ROOM,disabled=false,childLimit=3,lowLevelMark=1,midLevelMark=2,highLevelMark=3;id=7,parentId=1,name=ROOM7,displayIndex=7,modelCategory=ROOM,disabled=false,childLimit=3,lowLevelMark=1,midLevelMark=2,highLevelMark=3</entry></properties>";
        Properties properties = new Properties();
        
        try {
        properties.loadFromXML(new ByteArrayInputStream(xml.getBytes("utf-8")));
        } catch (Exception e) {
        throw new RuntimeException(e);
        }*/
//        PlayerProfile profile = (PlayerProfile) HibernateSessionFactory.getSession().createCriteria(
//                PlayerProfile.class).add(
//                Restrictions.eq("userId", "long")).add(
//                Restrictions.eq("password", "111111")).uniqueResult();

//        RoomResult room = new RoomResult();
//        room.getPlayers().add(new PlayerResult("1", "wang"));
//        room.getPlayers().add(new PlayerResult("2", "wang2"));
//        String jsonRct = gson.toJson(room);

        /* Map<String, Room> rooms = ModelUtil.getPlatform().getChild("1").getChildren();
        Room room;
        List<Room> roomsInQueue = new ArrayList<Room>();
        for (Room eachRoom : rooms.values()) {
        roomsInQueue.add(eachRoom);
        }   
        Collections.sort(roomsInQueue, new Comparator<Room>() {
        
        public int compare(Room p1, Room p2) {
        if (ConvertUtil.toInt(p1.getId()) > ConvertUtil.toInt(p2.getId())) {
        return 1;
        } else if (ConvertUtil.toInt(p1.getId()) < ConvertUtil.toInt(p2.getId())) {
        return -1;
        }
        return 0;
        }
        });
        String json = "[";
        RoomResult roomRlt;
        PlayerResult playerRlt;
        int count = 0;
        for (int i = 0; i < roomsInQueue.size(); i++) {
        room = roomsInQueue.get(i);
        if (room != null) {
        roomRlt = new RoomResult();
        roomRlt.setRid(room.getId());
        roomRlt.setRname(room.getName());
        for (Player player : room.getChildren().values()) {
        playerRlt = new PlayerResult(player.getId(), player.getName());
        roomRlt.getPlayers().add(playerRlt);
        }
        if (count == 0) {
        json += gson.toJson(roomRlt);
        } else {
        json += "," + gson.toJson(roomRlt);
        }
        count++;
        }
        
        }
        json += "]";
        System.out.println(json.replaceAll("\\s*|\t|\r|\n", ""));*/
//        String local = PropertiesHelper.getProperty("tankweb.properties", "isLocalDataBase");
        Base64 base64 = new Base64();
        String encodeString = new String(base64.encode("3~1335343878381~GAME_SNED_MESSAGE~我~0".getBytes()));
//输出结果将为"VGhpcyBpcyBzb3VyY2Ugc3RyaW5nLg=="
        System.out.println(encodeString);
//使用Base64进行字串解码
        String decodeString = new String(base64.decode(encodeString.getBytes()));
//输出结果将为"This is source string."
        System.out.println(decodeString);
        decodeString = new String(base64.decode("M34xMzM1MzQzODc4MzgxfkdBTUVfU05FRF9NRVNTQUdFfuaIkX4w".getBytes()));
//输出结果将为"This is source string."
        System.out.println(decodeString);
        System.out.println("1");
    }

    @SuppressWarnings("unchecked")
    protected static String toXML(EntityInfo<PlayerProfile> entityInfo, Class<?>... elementTypes) {
        XStream stream = new XStream();
        stream.alias(EntityInfo.class.getSimpleName(), EntityInfo.class);
        stream.registerConverter(new Converter() {

            public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) {
                Map<String, String> map = (Map<String, String>) value;
                Set<String> keys = ((Map<String, String>) value).keySet();
                for (String key : keys) {
                    StringBuilder prettyKey = new StringBuilder();
                    for (String innerKey : key.toLowerCase().split("_+")) {
                        prettyKey.append(innerKey.toUpperCase().charAt(0)).append(innerKey.substring(1));
                    }
                    writer.startNode(prettyKey.substring(0, 1).toLowerCase() + prettyKey.substring(1));
                    if (map.get(key) != null) {
                        writer.setValue(String.valueOf(map.get(key)));
                    }
                    writer.endNode();
                }
            }

            public Object unmarshal(HierarchicalStreamReader arg0, UnmarshallingContext arg1) {
                return null;
            }

            public boolean canConvert(Class type) {
                return Arrays.asList(type.getInterfaces()).contains(Map.class);
            }
        });
        if (elementTypes != null) {
            for (Class thisType : elementTypes) {
                stream.alias(thisType.getSimpleName().replaceAll("\\W", ""), thisType);
            }
        }
        stream.setMode(XStream.NO_REFERENCES);
        String responseText = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + stream.toXML(entityInfo);
        log.debug(responseText);
        return responseText;
    }

    class Chat_Thread extends Thread //与客户机进行通信的线程累
    {

        Socket socket; //套接字引用变量
        private BufferedReader reader;//引用套接字输入流；
        private PrintWriter writer;//引用套接字输出流；

        Chat_Thread(Socket socket)//构造函数
        {
            this.socket = socket;
        }

        public void run() {
            try {
                reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "utf8"));//utf8UTF-8
                //PrintWriter 的第二个参数：autoFlush - A boolean; if true, the println, printf, or format methods will flush the output buffer
                writer = new PrintWriter(socket.getOutputStream(), true);
                char[] ch = new char[22];
                reader.read(ch, 0, ch.length);
                StringBuffer sb = new StringBuffer();
                for (int i = 0; i < ch.length; i++) {
                    sb.append(ch[i]);
                }
                if (String.valueOf(sb.toString()).trim().equalsIgnoreCase("<policy-file-request/>")) {
                    //从输出流获取信息
                    writer.write("<?xml version=\"1.0\"?><cross-domain-policy><site-control permitted-cross-domain-policies=\"all\"/>  <allow-access-from domain=\"*\" to-ports=\"*\" /></cross-domain-policy>");
                    System.out.println(sb.toString());
                }
                String msg;

                while ((msg = reader.readLine()) != null && msg.trim() != "") {

                    if (String.valueOf(msg).trim().equalsIgnoreCase("exit")) {
                        break;
                    } else {
                        //向所有客户机传送信息
                        writer.write("hello");
                        System.out.println(msg);
                    }
                }
            } catch (IOException e) {
                try {
                    throw e;
                } catch (IOException ex) {
                    java.util.logging.Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }

//消息广播者类，继承Vector类
    class BManager extends Vector {

        BManager() {
        }//构造函数

        void add(Socket sock) {
            super.add(sock);//添加套接字
        }

        void remove(Socket sock) {
            super.remove(sock);//删除套接字
        }
        //向所有客户机传送消息，同步化方法。

        synchronized void sendToAll(String msg) {
            PrintWriter writer = null; //输出流
            Socket sock;  //套接字
            for (int i = 0; i < size(); i++) //执行循环
            {
                sock = (Socket) elementAt(i);//获取第i个套接字
                try {        //获取第i个套接字输出流
                    writer = new PrintWriter(sock.getOutputStream(), true);
                } catch (Exception ie) {
                }
//使用第i各套接字输出流，输出消息
                if (writer != null) {
                    writer.println(msg);
                }
            }
        }

        //向所有客户机发送当前聊天人数
        synchronized void sendClientInfo() {
            String info = "当前聊天人数：" + size();
            System.out.println(info);
            sendToAll(info);
        }
    }
}
